﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;

namespace AcceleratorTests
{
    public class ResultEntry
    {
        private string del = ";";

        string name;
        readonly float[,] GPURes;
        readonly float[,] CPURes;

        public ResultEntry(string name, float[,] GPURes, float[,] CPURes)
        {
            this.CPURes = CPURes;
            this.GPURes = GPURes;
            this.name = name;

            calculateAverages();
        }

        public float _maxDiff;
        public float _avgDiff;
        public float _deviation;

        public float maxDiff { get {return _maxDiff;}}
        public float avgDiff { get { return _avgDiff; } }
        public float deviation { get { return _deviation; } }

        void calculateAverages() {
                _maxDiff = 0;
                _avgDiff = 0;
                _deviation = 0;
                
                double diffsum = 0.0f;
                int diffcount = 0;

                for (int i = 0; i < CPURes.GetUpperBound(0); i++)
                {
                    for (int j = 0; j < CPURes.GetUpperBound(1); j++)
                    {
                        float c = CPURes[i, j];
                        float g = GPURes[i, j];
                        float diff = Math.Abs(g - c);
                        
                        _maxDiff = Math.Max(maxDiff, diff);

                        diffsum += diff;
                        diffcount++;
                    }
                }

                _avgDiff = (float)diffsum / diffcount;

                List<float> diffs = new List<float>();
                // Calculate Mean
                for (int i = 0; i < CPURes.GetUpperBound(0); i++)
                {
                    for (int j = 0; j < CPURes.GetUpperBound(1); j++)
                    {
                        float c = CPURes[i, j];
                        float g = GPURes[i, j];
                        float diff = Math.Abs(g - c);

                        diffs.Add((float)Math.Pow(avgDiff - diff, 2));
                    }
                }

                _deviation = (float)Math.Sqrt(diffs.Sum()/diffs.Count);
        }


        

        

        public void testResult()
        {
            bool isEq = true;
            if (CPURes.GetUpperBound(0) == GPURes.GetUpperBound(0) && CPURes.GetUpperBound(1) == GPURes.GetUpperBound(1))
            {
                for (int i = 0; i < CPURes.GetUpperBound(0); i++)
                {
                    for (int j = 0; j < CPURes.GetUpperBound(1); j++)
                    {
                        float c = CPURes[i, j];
                        float g = GPURes[i, j];
                        float diff = Math.Abs(g - c);
                        if (diff > 2f)
                        {
                           //System.Console.WriteLine(diff + " factor: " + diff / c);
                            isEq = false;
                        }
                    }
                }
            }
            else
            {
                System.Console.WriteLine("Dimensions are wrong");

                isEq = false;
            }
            if (!isEq)
            {
                //Console.WriteLine(name + " was wrong! Press Enter to continue");
                //Console.ReadLine();
            }



        }

        public void saveToFile(string p)
        {
            TextWriter tw = new StreamWriter(p);
            StringBuilder sbheader = new StringBuilder();
            //Write header!
            sbheader.Append("\"CPU\"");
            sbheader.Append(del);
            sbheader.Append("\"GPU\"");
            tw.WriteLine(sbheader);

            for (int i = 0; i < CPURes.GetUpperBound(0); i++)
            {
                for (int j = 0; j < CPURes.GetUpperBound(1); j++)
                {
                    StringBuilder sb = new StringBuilder();

                    sb.Append(CPURes[i,j]);
                    sb.Append(del);
                    sb.Append(GPURes[i, j]);

                    tw.WriteLine(sb.ToString());
                }
            }

        }

    }
}
